home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
emerald
/
emrldsys.lha
/
Language
/
Compiler
/
ident.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-16
|
4KB
|
164 lines
/*
* @(#)ident.c 1.3 9/24/87
*/
#include <stdio.h>
#include "ident.h"
#include "assert.h"
#define CASEFOLD
char *malloc();
#define PAGESIZE 1024
#define identsPerBlock (PAGESIZE)
#define charsPerBlock PAGESIZE
#define maxIdentElementBlocks 8
typedef struct identElementStruct {
Ident this;
char *name;
struct identElementStruct *next;
} IdentElement;
typedef IdentElement IdentElementBlock[identsPerBlock];
typedef int HashResultType;
static Ident nextIdentToAllocate = 0;
static char *fillPtr, *fillBase;
static IdentElementBlock *identElementBlockList[maxIdentElementBlocks];
static char hashvalues[128] =
{
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, 36, -1, 37, -1, -1, 38, -1,
-1, -1, 39, 40, -1, 41, -1, 42,
26, 27, 28, 29, 30, 31, 32, 33,
34, 35, -1, -1, 43, 44, 45, 46,
47, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, -1, -1, -1, 48, 49,
-1, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, -1, 50, -1, 51, -1
};
#define Value(x) ((int) hashvalues[x])
static HashResultType Hash (tokenText)
register char *tokenText;
{
#define R 52
register int result;
register int next;
next = *tokenText++;
result = Value(next);
result = result * R;
if (*tokenText != '\0') {
next = *tokenText++;
result = result + Value(next);
}
result = result * R;
if (*tokenText != '\0') {
next = *tokenText;
result = result + Value(next);
}
return(result);
}
static IdentElement *hashTable[256];
Ident Ident_Lookup(tokenText, tokenLength)
char *tokenText;
int tokenLength;
{
HashResultType x = Hash(tokenText);
#ifdef CASEFOLD
register char *l, *r;
#endif
register IdentElement *leader = hashTable[x % 256];
register IdentElement *follower = NULL;
register int compareResult;
register Ident resultIdent = Ident_nil;
IdentElementBlock **ieb;
register IdentElement *ie;
while (leader != NULL) {
#ifdef CASEFOLD
for (l = tokenText, r = leader->name; *l && *r; l++, r++) {
compareResult = ((*l) & ~0x20) - ((*r) & ~ 0x20);
if (compareResult) break;
}
if (compareResult == 0) compareResult = *l - *r;
#else
compareResult = strcmp(tokenText, leader->name);
#endif
if (compareResult == 0) {
resultIdent = leader->this;
break;
} else if (compareResult < 0) {
break;
} else {
follower = leader;
leader = leader->next;
}
}
if (resultIdent == Ident_nil) {
resultIdent = nextIdentToAllocate;
nextIdentToAllocate = nextIdentToAllocate + 1;
ieb = &identElementBlockList[resultIdent / identsPerBlock];
if (*ieb == NULL) {
*ieb = (IdentElementBlock *) malloc(sizeof(IdentElementBlock));
}
ie = &((**ieb)[resultIdent % identsPerBlock]);
if (tokenLength + 1 > charsPerBlock - (fillPtr - fillBase)) {
fillBase = malloc(charsPerBlock);
fillPtr = fillBase;
}
ie->name = fillPtr;
#ifdef CASEFOLD
for (l = fillPtr, r = tokenText; *r; l++, r++) {
if (*r >= 'A' && *r <= 'Z') *l = *r - 'A' + 'a';
else *l = *r;
}
*l = '\0';
#else
bcopy(tokenText, fillPtr, tokenLength + 1);
#endif CASEFOLD
fillPtr = fillPtr + tokenLength + 1;
ie->this = resultIdent;
ie->next = leader;
if (follower == NULL) {
hashTable[x % 256] = ie;
} else {
follower->next = ie;
}
}
return (resultIdent);
}
void Ident_Initialize()
{
bzero((char *)hashTable, sizeof(hashTable));
bzero((char *)identElementBlockList, sizeof(identElementBlockList));
fillBase = (char *) malloc(charsPerBlock);
fillPtr = fillBase;
}
char *Ident_Name(fIdent)
Ident fIdent;
{
register IdentElementBlock *ibp;
if (fIdent == -1) return ("<unknown>");
else {
ibp = identElementBlockList[fIdent / identsPerBlock];
if (ibp == NULL) return(NULL);
else return ((*ibp)[fIdent % identsPerBlock].name);
}
}